function varargout = iSelectAreas(varargin)
% ISELECTAREAS M-file for iSelectAreas.fig
%      ISELECTAREAS, by itself, creates a new ISELECTAREAS or raises the existing
%      singleton*.
%
%      H = ISELECTAREAS returns the handle to a new ISELECTAREAS or the handle to
%      the existing singleton*.
%
%      ISELECTAREAS('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in ISELECTAREAS.M with the given input arguments.
%
%      ISELECTAREAS('Property','Value',...) creates a new ISELECTAREAS or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before iSelectAreas_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to iSelectAreas_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help iSelectAreas

% Last Modified by GUIDE v2.5 25-Aug-2013 22:05:57

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @iSelectAreas_OpeningFcn, ...
                   'gui_OutputFcn',  @iSelectAreas_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Data handling related functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function OnOpen(handles)


global bClick;
global startx;
global starty;
global bObject;

global ox1s;
global oy1s;
global ox2s;
global oy2s;

global currentframe;
global ncurrentindex;
global nobjs; 
global ncurrentobject;
global totalframes;
global nobjecttypes;
global frames;
global nframes;
global nframesedited;


global inputfilefull;
global inputfile;

global detectareasfile;
global detectareasfilefull;

global selecttypesfilefull;
global selecttypesfile;

global v;


global selectareaspathname;
  

bClick = 0;
bObject = 0;
startx = 1;
starty = 1;
ncurrentobject = 0;


ox1s = [];
oy1s = [];
ox2s = [];
oy2s = [];    
    
nobjs = 0;
    
frames = {};
nobjecttypes = [];
nframes = [];

nframesedited = 0;
ncurrentindex = 0;
currentframe = 1;


selecttypesfilefull = '';
selecttypesfile = '';

selectareaspathname = '';


savefile = 'videoprocessdata.mat';
load(savefile);

if isempty(selecttypesfilefull)
    selecttypesfile = 'selecttypes.mat';
    selecttypesfilefull = 'selecttypes.mat';
    
    set(handles.editmetafile, 'String', selecttypesfile);
end


load(selecttypesfilefull);
UpdatePopupMenuTypes(handles);



if ~isempty(detectareasfilefull)
            
    vlen = length(detectareasfilefull);
    vfile = detectareasfilefull(1:vlen-10);
    vfile = strcat(vfile, '.avi');
    
    scheck = dir(vfile); 
    
    if ~isempty(scheck)        
        inputfilefull = vfile;
        inputfile = vfile;
        
        set(handles.editvideo, 'String', inputfile);        
    
        currentframe = 1;
        
        LoadDataFile(handles);
        
        v = mmreader(inputfilefull);
    
        totalframes = v.NumberOfFrames;        
    
        set(handles.editframe, 'String', num2str(currentframe));
        set(handles.texttotalframes, 'String', num2str(totalframes));
    
        ButtonGotoFrame(handles);                             
        set(handles.editdata, 'String', detectareasfile);
    end
elseif ~isempty(inputfilefull)
    scheck = dir(inputfilefull);
    if ~isempty(scheck);
        
        if isempty(inputfile)
            inputfile = inputfilefull;
        end
        
        detectareasfile = '';
        
        if ~isempty(inputfile)
            vlen = length(inputfile);
            
            detectareasfile = inputfile(1:vlen-4);
            detectareasfile = strcat(detectareasfile, '_areas.mat');
        end
            
        vlen = length(inputfilefull);
        
        detectareasfilefull = inputfilefull(1:vlen-4);
        detectareasfilefull = strcat(detectareasfilefull, '_areas.mat');
        
        if isempty(detectareasfile)
            detectareasfile = detectareasfilefull;
        end
                        
        
        set(handles.editvideo, 'String', inputfile);        
    
        currentframe = 1;
    
        LoadDataFile(handles);
        
        v = mmreader(inputfilefull);
    
        totalframes = v.NumberOfFrames;        
    
        set(handles.editframe, 'String', num2str(currentframe));
        set(handles.texttotalframes, 'String', num2str(totalframes));
    
        ButtonGotoFrame(handles);                             
        set(handles.editdata, 'String', detectareasfile);
        
        
        
    end
end



%{
return
   
[totalframes, FileName] = loadfile(nfile, angle, currentframe);


imgorg = img;
imshow(img)

FileName = strcat(FileName, '.mat');

len = length(FileName);
datafile = FileName(1:len-4);
datafile = strcat('sel_', datafile);
datafile = strcat(datafile, '.mat');


strtypes = {'Beak', 'Male', 'Female'};

if exist(datafile, 'file')
    load(datafile);
    
    if ~isempty(nframes) > 0
        ncurrentindex = 1;            
    
        LoadArrays();      
             
        currentframe = nframes(ncurrentindex);
        
        UpdateListBoxObjects(handles)
        UpdateListBoxFrames(handles)
        UpdateFrameNumber(handles, currentframe);
        DrawObjects();
    else
        
    end
else
    set(handles.listboxframes, 'String', '');
    set(handles.listboxobjects, 'String', '');        
end

set(handles.texttotalframes, 'String', num2str(totalframes));

UpdateFrame(handles)

sz = size(img);
imgx = sz(2);
imgy = sz(1);

textcolorred = [0.8471 0.1608  0];
textcolorblack = [0 0 0];

PathName = pwd;

CurrentVideoDirectory = PathName;
CurrentDataDirectory = PathName;

str = strcat(PathName, '/');
str = strcat(str, FileName);
%str = FileName;
set(handles.editvideo, 'String', str);

str = strcat(PathName, '/');
str = strcat(str, datafile);
%str = datafile;
set(handles.editdata, 'String', str);

load('selecttypes.mat');
UpdatePopupMenuTypes(handles);

%}



function SaveData(handles)
global frames;
global nframes;
global ncurrentindex;
global currentframe;
global ncurrentobject;

global v;
global strtypes;

global selectareaspathname;

len = length(nframes);


if len <= 0
    errordlg('No frames have been added, file has not been saved.')
    return
end

ncount = 0;

numberoftypes = length(strtypes);



ntotalobjs = 0;

for i = 1:len
    
    nobjecttypes = cell2mat(frames(i,6));        
    ntotalobjs = ntotalobjs + length(nobjecttypes);
end
        
        
if ntotalobjs == 0
    errordlg('No objects have been added, file has not been saved.')
    return
end
        

rmeans = zeros(ntotalobjs, numberoftypes);
rstds = zeros(ntotalobjs, numberoftypes);
gmeans = zeros(ntotalobjs, numberoftypes);
gstds = zeros(ntotalobjs, numberoftypes);
bmeans = zeros(ntotalobjs, numberoftypes);
bstds = zeros(ntotalobjs, numberoftypes);

imgdimensionsx = zeros(ntotalobjs, numberoftypes);
imgdimensionsy = zeros(ntotalobjs, numberoftypes);

meanxdim = zeros(numberoftypes, 1);
meanydim = zeros(numberoftypes, 1);
stdxdim = zeros(numberoftypes, 1);
stdydim = zeros(numberoftypes, 1);

nobjecttypecounts = zeros(numberoftypes, 1);


for i = 1:len %number of frames
    n = nframes(i);
    img = read(v,n);
     
    ox1s = cell2mat(frames(i,1));
    ox2s = cell2mat(frames(i,2));
    oy1s = cell2mat(frames(i,3));
    oy2s = cell2mat(frames(i,4));
    
    nobjecttypes = cell2mat(frames(i,6));
    
    lena = length(nobjecttypes);    

    
    for j = 1:lena  %number of areas in each frame        
      ncount = ncount + 1;            
      aimg = img(oy1s(j):oy2s(j), ox1s(j):ox2s(j),:); %image of area selected
      
      sz = size(aimg);
      
      rimg = aimg(:,:,1);
      gimg = aimg(:,:,2);
      bimg = aimg(:,:,3);
      
      fullimgs(ncount) = {aimg};
      rimgs(ncount) = {rimg};
      gimgs(ncount) = {gimg};
      bimgs(ncount) = {bimg};
      
      nobjecttype = nobjecttypes(j);
      imgtypes(ncount) = nobjecttype;                
          
      nobjecttypecounts(nobjecttype) = nobjecttypecounts(nobjecttype) + 1;
      
      nobjectsoftype = nobjecttypecounts(nobjecttype);
      [rmeans(nobjectsoftype,nobjecttype), rstds(nobjectsoftype,nobjecttype)] = CalcMeanStd(rimg);
      [gmeans(nobjectsoftype,nobjecttype), gstds(nobjectsoftype,nobjecttype)] = CalcMeanStd(gimg);
      [bmeans(nobjectsoftype,nobjecttype), bstds(nobjectsoftype,nobjecttype)] = CalcMeanStd(bimg); 
      
      rimgmeans(ncount) = rmeans(nobjectsoftype,nobjecttype);
      gimgmeans(ncount) = gmeans(nobjectsoftype,nobjecttype);
      bimgmeans(ncount) = bmeans(nobjectsoftype,nobjecttype);
      
      rimgstds(ncount) = rstds(nobjectsoftype,nobjecttype);
      gimgstds(ncount) = gstds(nobjectsoftype,nobjecttype);
      bimgstds(ncount) = bstds(nobjectsoftype,nobjecttype);
      
      imgdimensionsx(nobjectsoftype, nobjecttype) = sz(1);
      imgdimensionsy(nobjectsoftype, nobjecttype) = sz(2);
    end    
end


for i = 1:numberoftypes
    n = nobjecttypecounts(i);
    
    if n > 0
        meanxdim(i) = mean(imgdimensionsx(1:n, i));        
        stdxdim(i) = std(imgdimensionsx(1:n, i));
        
        meanydim(i) = mean(imgdimensionsy(1:n, i));
        stdydim(i) = std(imgdimensionsy(1:n, i));
    end
end


smetafile = get(handles.editmetafile, 'String');        
selecttypesfilefull = SaveGeneralDataFile(smetafile);
    
sfile = get(handles.editdata, 'String');
save(sfile, 'frames', 'nframes', 'ncurrentindex', 'ncurrentobject', 'currentframe', 'fullimgs',... 
            'imgtypes', 'rimgs', 'gimgs', 'bimgs', 'ntotalobjs', 'rmeans', 'rstds',...
            'gmeans', 'gstds', 'bmeans', 'bstds', 'nobjecttypecounts', 'numberoftypes',...
            'rimgmeans', 'gimgmeans', 'bimgmeans', 'rimgstds', 'gimgstds', 'bimgstds',...
            'imgdimensionsx', 'imgdimensionsy', 'meanxdim', 'stdxdim', 'meanydim', 'stdydim',...
            'selecttypesfilefull');
        
        
set(handles.textevents, 'String', 'Data successfully saved');





function selecttypesfilefull = SaveGeneralDataFile(smetafile)

global selecttypesfilefull;
global selecttypesfile;

global selectareaspathname;

selecttypesfile = '';
selecttypesfilefull = '';
load('videoprocessdata.mat');

if ~isempty(selectareaspathname) | isempty(selecttypesfilefull)
    selecttypesfile = smetafile;
    selecttypesfilefull = strcat(selectareaspathname, smetafile);
    
    clear smetafile;
    
    save('videoprocessdata.mat');
end





function [dmean, dstd] = CalcMeanStd(b)

dmean = mean(b(:));
dstd = sqrt(sum( (b(:)-mean(b(:))).^2 )/(length(b)-1)); %matlab std occasionally crashes so 'manually' calculate std
      
      


function AddObject(handles)

global x1;
global x2;
global y1;
global y2;

global ox1s;
global oy1s;
global ox2s;
global oy2s;

global nobjs; 

global nobjecttypes;

global totalframes;


global ncurrentobject;

if x1 > 0 & x2 > 0 & y1 > 0 & y2 > 0 & totalframes > 0    
    
    npopindex = get(handles.popupmenutypes, 'Value');         
      
    nobjs = nobjs + 1;    
    ncurrentobject = nobjs;    
      
    ox1s(nobjs) = x1;
    ox2s(nobjs) = x2;
    oy1s(nobjs) = y1;
    oy2s(nobjs) = y2;
          
    nobjecttypes(nobjs) = npopindex;   
    
    UpdateListBoxObjects(handles);
    
    DrawObjects();       
    
    x1 = 0;
    x2 = 0;
    y1 = 0;
    y2 = 0;
    
    SaveFrame(handles)
end


function RemoveObject(handles)

global ox1s;
global oy1s;
global ox2s;
global oy2s;

global ncurrentindex;
global nobjs; 

global nobjecttypes;


global ncurrentobject;

if ncurrentindex <= 0
    return
end

if nobjs > 0 & ncurrentobject > 0 
    
    %ncurrentindex
    %ncurrentobject
    %size(ox1s)
    
    ox1s(ncurrentobject) = [];
    ox2s(ncurrentobject) = [];
    oy1s(ncurrentobject) = [];
    oy2s(ncurrentobject) = [];
    
    nobjecttypes(ncurrentobject) = [];
    
    
    nobjs = nobjs - 1;
    
    if nobjs == 0
        
    else
        if ncurrentobject > nobjs
            ncurrentobject = ncurrentobject - 1;
        end            
    end
    
    UpdateListBoxObjects(handles)
    DrawObjects()        
    SaveFrame(handles)
end


function UpdateObjects(handles)


global ncurrentindex;
global ncurrentobject;
global nobjecttypes;



nindex = get(handles.listboxobjects, 'Value');
if nindex > 0
    ncurrentobject = nindex;
end

npopindex = get(handles.popupmenutypes, 'Value');


nobjecttypes(ncurrentobject) = npopindex;

UpdateListBoxObjects(handles)
DrawObjects()
SaveFrame(handles)



function RemoveFrame(handles)

global frames;
global nframes;
global ncurrentindex;
global currentframe;
global ncurrentobject;

if ncurrentindex <= 0 
    str = 'Current frame ('; 
    str = strcat(str, num2str(currentframe)); 
    str = strcat(str, ') ');
    str = strcat(str, ' data does not exist. Click under Frames to select a different frame.');
    
    bwarn = 1;
    
    UpdateTextEvent(handles, str, bwarn);
    
    return
end

frames(ncurrentindex,:) = [];
nframes(ncurrentindex) = [];
ResetArrays();

ncurrentindex = 0;
ncurrentobject = 0;


UpdateListBoxObjects(handles)
UpdateListBoxFrames(handles)
DrawObjects()        

    
    

function SaveFrame(handles)

global frames;

global ox1s;
global ox2s;
global oy1s;
global oy2s;

global ncurrentindex;
global currentframe;
global nobjs; 

global nobjecttypes;


global nframes;

global totalframes;

if totalframes == 0
    return;
end

a = find(nframes == currentframe, 1);

if isempty(a)
    %nframesedited
    %nframesedited = nframesedited + 1;
    
    len = length(nframes);    
    ncurrentindex = len + 1;
    nframes(ncurrentindex) = currentframe;            
else
    ncurrentindex = a;            
end

frames(ncurrentindex,:) = {ox1s, ox2s, oy1s, oy2s, nobjs, nobjecttypes};

UpdateListBoxFrames(handles)




function ResetArrays()

global ox1s;
global ox2s;
global oy1s;
global oy2s;

global nobjs; 

global nobjecttypes;



ox1s = [];
ox2s = [];
oy1s = [];
oy2s = [];

nobjs = 0;
nobjecttypes = [];


function LoadArrays()

global frames;

global ox1s;
global ox2s;
global oy1s;
global oy2s;

global nobjs; 

global nobjecttypes;


global ncurrentindex; 

if ncurrentindex > 0
    ox1s = cell2mat(frames(ncurrentindex, 1));
    ox2s = cell2mat(frames(ncurrentindex, 2));
    oy1s = cell2mat(frames(ncurrentindex, 3));
    oy2s = cell2mat(frames(ncurrentindex, 4));
    nobjs = cell2mat(frames(ncurrentindex, 5));
    nobjecttypes = cell2mat(frames(ncurrentindex, 6));
end




function DrawObjects()

global ox1s;
global oy1s;
global ox2s;
global oy2s;

global nobjs; 
global nobjecttypes;

global imgorg;
global img;

global ncurrentobject;


if nobjs > 0
    
    img = imgorg;
    
    for i = 1:nobjs
                
        x1 = ox1s(i);
        x2 = ox2s(i);
        y1 = oy1s(i);
        y2 = oy2s(i);                        
        
        ng = nobjecttypes(i);    
        
        

        if i == ncurrentobject
             r = 250;
             g = 80;
             b = 80;
        else
             r = 200;
             g = 50;
             b = 50;
        end
         
        %{
        if i == ncurrentobject
            switch ng        
                case 0 %female
                    r = 255;
                    g = 170;
                    b = 210;
                case 1 %male
                    r = 115;
                    g = 235;
                    b = 115;
                case 2 %none
                    r = 250;
                    g = 80;
                    b = 80;
            end
        else
            switch ng        
                case 0 %female
                    r = 240;
                    g = 130;
                    b = 171;
                case 1 %male
                    r = 100;
                    g = 210;
                    b = 70;
                case 2 %none
                    r = 200;
                    g = 50;
                    b = 50;
            end
        end
        %}
        
        img(y1, x1:x2, 1) = r;
        img(y1, x1:x2, 2) = g;
        img(y1, x1:x2, 3) = b;
        
        img(y2, x1:x2, 1) = r;
        img(y2, x1:x2, 2) = g;
        img(y2, x1:x2, 3) = b;
                
        img(y1:y2, x1, 1) = r;
        img(y1:y2, x1, 2) = g;
        img(y1:y2, x1, 3) = b;
        
        img(y1:y2, x2, 1) = r;
        img(y1:y2, x2, 2) = g;
        img(y1:y2, x2, 3) = b;
        
        %{
        img(y1-1:y1+1, x1:x2, 1) = r;
        img(y1-1:y1+1, x1:x2, 2) = g;
        img(y1-1:y1+1, x1:x2, 3) = b;
        
        img(y2-1:y2+1, x1:x2, 1) = r;
        img(y2-1:y2+1, x1:x2, 2) = g;
        img(y2-1:y2+1, x1:x2, 3) = b;
        
        img(y1:y2, x1-1:x1+1, 1) = r;
        img(y1:y2, x1-1:x1+1, 2) = g;
        img(y1:y2, x1-1:x1+1, 3) = b;
        
        img(y1:y2, x2-1:x2+1, 1) = r;
        img(y1:y2, x2-1:x2+1, 2) = g;
        img(y1:y2, x2-1:x2+1, 3) = b;
        %}
        
    end          
else
    img = imgorg;    
end

imshow(img)


function OpenVideoFile(handles)
global pathname;
global inputfile;
global inputfilefull;

global detectareasfile;
global detectareasfilefull;

global totalframes;
global currentframe;
global v;

[filename, pathname] = uigetfile( ...
{'*.avi; *.mpg; *.mpeg; *.mov','Video Files (*.avi, *.mpg, *.mpeg, *.mov)';   
 '*.*',  'All Files (*.*)'}, ...
 'Pick a file');

if filename ~= 0    
            
    inputfile = filename;
    inputfilefull = strcat(pathname, filename);
    
    set(handles.editvideo, 'String', filename);        
    
    currentframe = 1;
    
    v = mmreader(inputfilefull);
    
    totalframes = v.NumberOfFrames;        
    
    set(handles.editframe, 'String', num2str(currentframe));
    set(handles.texttotalframes, 'String', num2str(totalframes));
    
    ButtonGotoFrame(handles)                   
    
    len = length(filename);
    detectareasfile = strcat(filename(1:len-4), '_areas.mat');
    detectareasfilefull = strcat(pathname, detectareasfile);
        
    set(handles.editdata, 'String', detectareasfile);
        
    LoadDataFile(handles)
    
end


function LoadDataFile(handles)


global ncurrentindex; 
global ncurrentobject; 
global currentframe;
global frames;
global v;

global detectareasfilefull;

if isempty(detectareasfilefull)
    return
end

scheck = dir(detectareasfilefull);

if isempty(scheck)
    return
end

load(detectareasfilefull);

LoadArrays();

UpdateListBoxObjects(handles)
UpdateListBoxFrames(handles)


if ~isempty(v)
    GotoFrame(handles)
    set(handles.editframe, 'String', num2str(currentframe));
end



function OpenDataFile(handles)
global pathname;
global detectareasfile;
global detectareasfilefull;

[filename,pathname] = uigetfile({'*.mat','Data Files (*.mat)';'*.*',  'All Files (*.*)'},'Pick a file');

if filename ~= 0    
    detectareasfile = filename;
    detectareasfilefull = strcat(pathname, filename);    
    
    set(handles.editdata, 'String', filename);
    
    LoadDataFile(handles)
end





function OpenMetaFile(handles)


global inputfile;
global inputfilefull;

global detectareasfile;
global detectareasfilefull;

global selectareaspathname;


global bClick;
global startx;
global starty;
global bObject;

global ox1s;
global oy1s;
global ox2s;
global oy2s;

global currentframe;
global ncurrentindex;

global ncurrentobject;
global totalframes;
global nframesedited;


global inputfilefull;
global inputfile;

global detectareasfile;
global detectareasfilefull;

global v;

global nobjs; 
global nobjecttypes;
global frames;
global nframes;


global inputfilefull;
global inputfile;

global detectareasfile;
global detectareasfilefull;

global v;


global selectareaspathname;
  

[filename,selectareaspathname] = uigetfile({'*.mat','Data Files (*.mat)';'*.*',  'All Files (*.*)'},'Pick a file');

if filename ~= 0    
    
    set(handles.editmetafile, 'String', filename);
   
           
    inputfile = '';
    inputfilefull = '';

    detectareasfile = '';
    detectareasfilefull = '';        
    
    bClick = 0;
    bObject = 0;
    startx = 1;
    starty = 1;
    ncurrentobject = 0;
    
    
    ox1s = [];
    oy1s = [];
    ox2s = [];
    oy2s = [];    
    
    nobjs = 0;
    
    frames = {};
    nobjecttypes = [];
    nframes = [];

    nframesedited = 0;
    ncurrentindex = 0;
    currentframe = 1;
    totalframes = 0;
    
        
    UpdateListBoxObjects(handles);
    UpdateListBoxFrames(handles);
    UpdatePopupMenuTypes(handles);
    
    set(handles.editvideo, 'String', '');
    set(handles.editdata, 'String', '');
    set(handles.editframe, 'String', 0);
    set(handles.texttotalframes, 'String', 0);
    
    v = [];
    
    cla reset;
    
end





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Interface change/update related functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%








function ClearTextEvent(obj, event, handles) 

set(handles.textevents, 'String', '');


function UpdateTextEvent(handles, str, bwarn)

global textcolorblack;
global textcolorred;

if bwarn == 1
    set(handles.textevents, 'ForegroundColor', textcolorred);
else
    set(handles.textevents, 'ForegroundColor', textcolorblack);
end

set(handles.textevents, 'String', str);

t = timer('TimerFcn',{@ClearTextEvent, handles}, 'StartDelay', 8.0); 

start(t)




function UpdatePopupMenuTypes(handles)
global strtypes;

len = length(strtypes);


if isempty(strtypes)
    load('selecttypes.mat');
    len = length(strtypes);
end

for i = 1:len
    str(i, :) = strtypes(i);
end

set(handles.popupmenutypes, 'String', str);
    




function UpdateListBoxObjects(handles)
global ox1s;
global ox2s;
global oy1s;
global oy2s;
global nobjecttypes;
global ncurrentobject;
global nobjs;
global strtypes;

if nobjs > 0
    for i = 1:nobjs
        
        sg = strtypes(nobjecttypes(i));       
        
        s1 = num2str(ox1s(i));
        s2 = num2str(ox2s(i));
        s3 = num2str(oy1s(i));
        s4 = num2str(oy2s(i));
                    
        str(i,:) = strcat(sg, {'  (h'}, s1, '-', s2, {'  v'}, s3, '-', s4, ')');            
    end    
else
    str = '';
end

if ncurrentobject > nobjs
    ncurrentobject = nobjs;
end
    
set(handles.listboxobjects, 'String', str);

if ncurrentobject > 0 
    set(handles.listboxobjects, 'Value', ncurrentobject);
end


function UpdateListBoxFrames(handles)
global nframes;
global ncurrentindex;


set(handles.listboxframes, 'String', num2str(nframes'));

len = length(nframes); 

if ncurrentindex > len
    ncurrentindex = len;
end

if len > 0
    if ncurrentindex > 0
        set(handles.listboxframes, 'Value', ncurrentindex);
    else
        set(handles.listboxframes, 'Value', 1);
    end
else
    set(handles.listboxframes, 'Value', 0);
end



function UpdateFrame(handles)

global totalframes; 
global currentframe;

set(handles.editframe, 'String', num2str(currentframe));

d = currentframe/totalframes;
set(handles.sliderframe, 'Value', d);



function GotoFrame(handles)

global ncurrentindex;
global currentframe;
global ncurrentobject;

global inputfilefull;
global nframes;
global img;
global imgorg;
global v;
global totalframes;

global imgx;
global imgy;


svideo = get(handles.editvideo, 'String');

if isempty(v) & isempty(inputfilefull) & isempty(svideo)
    return
elseif isempty(v) & isempty(inputfilefull)
    inputfilefull = svideo;
end

if isempty(v)    
    v = mmreader(inputfilefull);
    currentframe = 1;
    totalframes = v.NumberOfFrames;
   
    set(handles.editframe, 'String', num2str(currentframe));
    set(handles.texttotalframes, 'String', num2str(totalframes));    
end

if currentframe > totalframes
    currentframe = totalframes;
end

if currentframe <=0
    currentframe = 1;
end

img = read(v,currentframe);
imgorg = img;

sz = size(img);
imgx = sz(2);
imgy = sz(1);

a = find(nframes == currentframe, 1);

if isempty(a)            
    ncurrentindex = 0;
    ResetArrays();
    imshow(img);   
    
    UpdateListBoxObjects(handles)
else
    ncurrentindex = a;   

    LoadArrays();    
    DrawObjects();
    
    UpdateListBoxObjects(handles);
    ncurrentobject = get(handles.listboxobjects, 'Value');
end
    


function UpdateFrameNumber(handles, n)
global totalframes;

set(handles.editframe, 'String', num2str(n));

d = n/totalframes;
set(handles.sliderframe, 'Value', d);
    
GotoFrame(handles);





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Functions called by event handlers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function ButtonGotoFrame(handles)

global totalframes; 
global currentframe;

scurrentframe = get(handles.editframe, 'String');
n = str2num(scurrentframe);

if n > 0 & n <= totalframes
    currentframe = n;
    
    d = currentframe/totalframes;
    set(handles.sliderframe, 'Value', d);
    
    GotoFrame(handles)
end



function SliderGotoFrame(handles)

global totalframes; 
global currentframe;

n = get(handles.sliderframe, 'Value');
currentframe = floor(totalframes*n)+1;

if currentframe > totalframes
    currentframe = totalframes;
end

set(handles.editframe, 'String', num2str(currentframe));
GotoFrame(handles)



function ListBoxFrameClicked(handles)

global currentframe;
global nframes;
global totalframes; 

n = get(handles.listboxframes, 'Value');

if n > 0
    s = get(handles.listboxframes, 'String');
       
    nframe = str2num(s(n,:));        
        
    a = find(nframes == nframe, 1);        
    
    if ~isempty(a)
        currentframe = nframe;
                             
        set(handles.editframe, 'String', num2str(currentframe));
                
        d = currentframe/totalframes;
                
        set(handles.sliderframe, 'Value', d);            
    
        GotoFrame(handles)
    end
end


function ListBoxObjectsClicked(handles)

global ncurrentobject;

nindex = get(handles.listboxobjects, 'Value');

if nindex > 0
    ncurrentobject = nindex;
end

DrawObjects()




function MouseButtonDown(handles)
global bClick;
global img;
global imgorg;
global imgx;
global imgy;
global startx; 
global starty;
global bObject;

global x1; 
global x2; 
global y1; 
global y2; 

global totalframes;

if totalframes == 0
    return;
end

set(handles.textevents, 'String', '');

point = get(gca,'CurrentPoint');

x = point(1,1);
y = point(1,2);

if x > 0 & y > 0 & x <= imgx & y <= imgy        
    
    x1 = 0;
    x2 = 0;
    y1 = 0;
    y2 = 0;

    bClick = 1;
    bObject = 0;
    img = imgorg;
    DrawObjects();
    
    imshow(img)
    
    startx = x;
    starty = y;
end
    


function MouseButtonUp(handles)
global bClick;
global startx; 
global starty;
global bObject;

global totalframes;

if totalframes == 0
    return;
end


bClick = 0;

startx = 1;
starty = 1;



function MouseMoved(handles)

global bClick;
global img;
global imgorg;
global startx; 
global starty;
global imgx;
global imgy;
global bObject;

global x1; 
global x2;
global y1; 
global y2;

global totalframes;

if totalframes == 0
    return;
end


if bClick == 1
    point = get(gca,'CurrentPoint');
    
    x = point(1,1);
    y = point(1,2);

    if x > 0 & y > 0 & x <= imgx & y <= imgy
        bClick = 1;
        bObject = 1;
        
        img = imgorg;
        DrawObjects();
        
        if x > startx
            x1 = startx;
            x2 = x;
        else
            x1 = x;
            x2 = startx;            
        end
        
        if y > starty
            y1 = starty;
            y2 = y;
        else
            y1 = y;
            y2 = starty; 
        end
        
        x1 = round(x1);
        x2 = round(x2);
        y1 = round(y1);
        y2 = round(y2);
        
        nval = 255;
        
        img(y1, x1:x2, :) = nval;
        img(y2, x1:x2, :) = nval;
        img(y1:y2, x1, :) = nval;
        img(y1:y2, x2, :) = nval;
        
        %{
        img(y1-1:y1+1, x1:x2, :) = nval;
        img(y2-1:y2+1, x1:x2, :) = nval;
        img(y1:y2, x1-1:x1+1, :) = nval;
        img(y1:y2, x2-1:x2+1, :) = nval;
        %}
        
        imshow(img)
    end
end













%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Event handlers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% --- Executes just before iSelectAreas is made visible.
function iSelectAreas_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to iSelectAreas (see VARARGIN)

% Choose default command line output for iSelectAreas
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes iSelectAreas wait for user response (see UIRESUME)
% uiwait(handles.figure1);

OnOpen(handles)


% --- Outputs from this function are returned to the command line.
function varargout = iSelectAreas_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;



% --- Executes during object creation, after setting all properties.
function axesselectareas_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axesselectareas (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axesselectareas


% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

MouseButtonDown(handles)
set(handles.textevents, 'String', '');


% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonUpFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

MouseButtonUp(handles)


% --- Executes on mouse motion over figure - except title and menu.
function figure1_WindowButtonMotionFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

MouseMoved(handles)



% --- Executes on selection change in listboxobjects.
function listboxobjects_Callback(hObject, eventdata, handles)
% hObject    handle to listboxobjects (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns listboxobjects contents as cell array
%        contents{get(hObject,'Value')} returns selected item from listboxobjects

ListBoxObjectsClicked(handles)



% --- Executes during object creation, after setting all properties.
function listboxobjects_CreateFcn(hObject, eventdata, handles)
% hObject    handle to listboxobjects (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: listbox controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttonsf.
function pushbuttonsf_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonsf (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

SaveFrame(handles)

% --- Executes on selection change in listboxframes.
function listboxframes_Callback(hObject, eventdata, handles)
% hObject    handle to listboxframes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns listboxframes contents as cell array
%        contents{get(hObject,'Value')} returns selected item from listboxframes

ListBoxFrameClicked(handles)


% --- Executes during object creation, after setting all properties.
function listboxframes_CreateFcn(hObject, eventdata, handles)
% hObject    handle to listboxframes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: listbox controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --- Executes on button press in pushbuttonro.
function pushbuttonro_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonro (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

RemoveObject(handles);



% --- Executes on button press in pushbuttondf.
function pushbuttondf_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttondf (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

RemoveFrame(handles)



% --- Executes on button press in pushbuttonupdate.
function pushbuttonupdate_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonupdate (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

UpdateObjects(handles)


% --- Executes on slider movement.
function sliderframe_Callback(hObject, eventdata, handles)
% hObject    handle to sliderframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderGotoFrame(handles)


% --- Executes during object creation, after setting all properties.
function sliderframe_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end



function editframe_Callback(hObject, eventdata, handles)
% hObject    handle to editframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editframe as text
%        str2double(get(hObject,'String')) returns contents of editframe as a double


% --- Executes during object creation, after setting all properties.
function editframe_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttongo.
function pushbuttongo_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttongo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

ButtonGotoFrame(handles)


% --- Executes on button press in pushbuttonadd.
function pushbuttonadd_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonadd (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

AddObject(handles)



function editvideo_Callback(hObject, eventdata, handles)
% hObject    handle to editvideo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editvideo as text
%        str2double(get(hObject,'String')) returns contents of editvideo as a double


% --- Executes during object creation, after setting all properties.
function editvideo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editvideo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function editdata_Callback(hObject, eventdata, handles)
% hObject    handle to editdata (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editdata as text
%        str2double(get(hObject,'String')) returns contents of editdata as a double


% --- Executes during object creation, after setting all properties.
function editdata_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editdata (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttoopenvideo.
function pushbuttoopenvideo_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttoopenvideo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

set(handles.textevents, 'String', 'Loading...');
   
OpenVideoFile(handles)

set(handles.textevents, 'String', '');    

% --- Executes on button press in pushbuttonopendata.
function pushbuttonopendata_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonopendata (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

OpenDataFile(handles);

% --- Executes on button press in pushbuttonsave.
function pushbuttonsave_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonsave (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

SaveData(handles);






% --- Executes when selected object is changed in uipanel4.
function uipanel4_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in uipanel4 
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)

TrainTestButtonChanged(handles);


% --- Executes on selection change in popupmenutypes.
function popupmenutypes_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenutypes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenutypes contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenutypes


% --- Executes during object creation, after setting all properties.
function popupmenutypes_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenutypes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttoncancel.
function pushbuttoncancel_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttoncancel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

close();


% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over sliderframe.
function sliderframe_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to sliderframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on mouse press over axes background.
function axesselectareas_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axesselectareas (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on mouse press over figure background.
function figure1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



function editmetafile_Callback(hObject, eventdata, handles)
% hObject    handle to editmetafile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editmetafile as text
%        str2double(get(hObject,'String')) returns contents of editmetafile as a double


% --- Executes during object creation, after setting all properties.
function editmetafile_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editmetafile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttonmetafile.
function pushbuttonmetafile_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonmetafile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


OpenMetaFile(handles);
